﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using log4net;
using Mrb.Utils;

namespace PictureOrganizer
{
    public class PictureOrganizerProcess : IBatchProcess
    {
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private IEnumerable<SourceFolder> _sourceFolders;
        private string _baseFolder;
        private string _allFolder;
        private IEnumerable<string> _ignoredFileExtensions;

        public void Open(Configuration config)
        {
            _sourceFolders = config.ParseJsonArray<SourceFolder>("folders");
            _baseFolder = config["pictures.basefolder"];
            _allFolder = config["pictures.allfolder"];
            _ignoredFileExtensions = config["pictures.ignoredfileextensions"].Split(',');
        }

        public void Run()
        {
            var allDirectory = @"{0}\{1}".Fmt(_baseFolder, _allFolder);
            Directory.CreateDirectory(allDirectory);
            var existingFiles = Directory.GetFiles(allDirectory);
            foreach (var sourceFolder in _sourceFolders)
            {
                var path = @"{0}\{1}".Fmt(_baseFolder, sourceFolder.Name);
                var files = Directory.GetFiles(path);

                var lastFileDate = DateTime.MinValue;
                foreach (var file in files)
                {
                    var fileInfo = new FileInfo(file);
                    if (_ignoredFileExtensions.Contains(fileInfo.Extension))
                    {
                        continue;
                    }
                    var sourceFileName = file.Split('\\').Last();
                    var fileRoot = sourceFileName.Split('.')[0];
                    if (existingFiles.Any(f => f.EndsWith("{0}-{1}.JPG".Fmt(sourceFolder.FolderId, fileRoot))))
                    {
                        continue;
                    }
                    var dateTaken = GetDateTaken(file);
                    if (lastFileDate > dateTaken)
                    {
                        Console.Write("");
                    }
                    lastFileDate = dateTaken;
                    var destFileName = @"{0}\{1}-{2}-{3}{4}".Fmt(allDirectory,
                                                                 dateTaken.ToString("yyyyMMdd-HHmmss"),
                                                                 sourceFolder.FolderId, fileRoot,
                                                                 fileInfo.Extension);

                    if (File.Exists(destFileName))
                    {
                        continue;
                    }
                    var msg = "Copying file from {0} to {1}".Fmt(file, destFileName);
                    Console.WriteLine(msg);
                    Log.Info(msg);
                    File.Copy(file, destFileName, true);
                    GC.Collect();
                }
            }
        }

        private DateTime GetDateTaken(string path)
        {
            var fileInfo = new FileInfo(path);
            //return fileInfo.LastWriteTime.Min(fileInfo.CreationTime);
            if (fileInfo.Extension.ToLower() != ".jpg")
            {
                return fileInfo.LastWriteTime;
            }
            using (var fstream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                var image = Image.FromStream(fstream);
                var propItem = image.GetPropertyItem(36867);
                var dateTaken = new Regex(":").Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
                return DateTime.Parse(dateTaken);
            }
        }
    }
}